/**
 */
package fUML.Semantics.CommonBehaviors.Communications;

import fUML.Semantics.CommonBehaviors.BasicBehaviors.ParameterValue;

import org.eclipse.emf.common.util.EList;

import org.eclipse.emf.ecore.EObject;

/**
 * <!-- begin-user-doc -->
 * A representation of the model object '<em><b>Object Activation</b></em>'.
 * <!-- end-user-doc -->
 *
 * <!-- begin-model-doc -->
 * An object activation handles the active behavior of an active object.
 * <!-- end-model-doc -->
 *
 * <p>
 * The following features are supported:
 * <ul>
 *   <li>{@link fUML.Semantics.CommonBehaviors.Communications.ObjectActivation#getWaitingEventAccepters <em>Waiting Event Accepters</em>}</li>
 *   <li>{@link fUML.Semantics.CommonBehaviors.Communications.ObjectActivation#getEventPool <em>Event Pool</em>}</li>
 *   <li>{@link fUML.Semantics.CommonBehaviors.Communications.ObjectActivation#getObject <em>Object</em>}</li>
 *   <li>{@link fUML.Semantics.CommonBehaviors.Communications.ObjectActivation#getClassifierBehaviorExecutions <em>Classifier Behavior Executions</em>}</li>
 * </ul>
 * </p>
 *
 * @see fUML.Semantics.CommonBehaviors.Communications.CommunicationsPackage#getObjectActivation()
 * @model
 * @generated
 */
public interface ObjectActivation extends EObject {
	/**
	 * Returns the value of the '<em><b>Waiting Event Accepters</b></em>' reference list.
	 * The list contents are of type {@link fUML.Semantics.CommonBehaviors.Communications.EventAccepter}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * The set of event accepters waiting for signals to be received by the object of
	 *                   this object activation.
	 * <!-- end-model-doc -->
	 * @return the value of the '<em>Waiting Event Accepters</em>' reference list.
	 * @see fUML.Semantics.CommonBehaviors.Communications.CommunicationsPackage#getObjectActivation_WaitingEventAccepters()
	 * @model ordered="false"
	 * @generated
	 */
	EList<EventAccepter> getWaitingEventAccepters();

	/**
	 * Returns the value of the '<em><b>Event Pool</b></em>' containment reference list.
	 * The list contents are of type {@link fUML.Semantics.CommonBehaviors.Communications.SignalInstance}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * The pool of signals sent to the object of this object activation, pending
	 *                   dispatching as events.
	 *  (All the data values in the pool must be signal
	 *                   instances -- that is, they must have a single type that is a signal.)
	 * <!-- end-model-doc -->
	 * @return the value of the '<em>Event Pool</em>' containment reference list.
	 * @see fUML.Semantics.CommonBehaviors.Communications.CommunicationsPackage#getObjectActivation_EventPool()
	 * @model containment="true"
	 * @generated
	 */
	EList<SignalInstance> getEventPool();

	/**
	 * Returns the value of the '<em><b>Object</b></em>' container reference.
	 * It is bidirectional and its opposite is '{@link fUML.Semantics.Classes.Kernel.Object#getObjectActivation <em>Object Activation</em>}'.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * The object whose active behavior is being handled by this active
	 *                 object.
	 * <!-- end-model-doc -->
	 * @return the value of the '<em>Object</em>' container reference.
	 * @see #setObject(fUML.Semantics.Classes.Kernel.Object)
	 * @see fUML.Semantics.CommonBehaviors.Communications.CommunicationsPackage#getObjectActivation_Object()
	 * @see fUML.Semantics.Classes.Kernel.Object#getObjectActivation
	 * @model opposite="objectActivation" required="true" transient="false" ordered="false"
	 * @generated
	 */
	fUML.Semantics.Classes.Kernel.Object getObject();

	/**
	 * Sets the value of the '{@link fUML.Semantics.CommonBehaviors.Communications.ObjectActivation#getObject <em>Object</em>}' container reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @param value the new value of the '<em>Object</em>' container reference.
	 * @see #getObject()
	 * @generated
	 */
	void setObject(fUML.Semantics.Classes.Kernel.Object value);

	/**
	 * Returns the value of the '<em><b>Classifier Behavior Executions</b></em>' containment reference list.
	 * The list contents are of type {@link fUML.Semantics.CommonBehaviors.Communications.ClassifierBehaviorExecution}.
	 * It is bidirectional and its opposite is '{@link fUML.Semantics.CommonBehaviors.Communications.ClassifierBehaviorExecution#getObjectActivation <em>Object Activation</em>}'.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * The executing classifier behaviors for this object activation.
	 * <!-- end-model-doc -->
	 * @return the value of the '<em>Classifier Behavior Executions</em>' containment reference list.
	 * @see fUML.Semantics.CommonBehaviors.Communications.CommunicationsPackage#getObjectActivation_ClassifierBehaviorExecutions()
	 * @see fUML.Semantics.CommonBehaviors.Communications.ClassifierBehaviorExecution#getObjectActivation
	 * @model opposite="objectActivation" containment="true" ordered="false"
	 * @generated
	 */
	EList<ClassifierBehaviorExecution> getClassifierBehaviorExecutions();

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Start the event dispatch loop for this object activation (if it has not
	 *                   already been started).
	 *  // If a classifier is given that is a type of the
	 *                   object of this object activation and there is not already a classifier behavior
	 *                   execution for it, 
	 *  // then create a classifier behavior execution for
	 *                   it.
	 *  // Otherwise, create a classifier behavior execution for each of the
	 *                   types of the object of this object activation which has a classifier behavior or
	 *                   which is a behavior itself 
	 *  // and for which there is not currently a
	 *                   classifier behavior execution.
	 *  
	 *  // Start
	 *                   EventDispatchLoop
	 *  _startObjectBehavior();
	 *  
	 *  if
	 *                   (classifier == null) {
	 *  Debug.println("[startBehavior] Starting behavior
	 *                   for all classifiers...");
	 *  // *** Start all classifier behaviors
	 *                   concurrently. ***
	 *  Class_List types = this.object.types;
	 *  for
	 *                   (Iterator i = types.iterator(); i.hasNext();) {
	 *  Class_ type =
	 *                   (Class_)i.next();
	 *  if (type instanceof Behavior | type.classifierBehavior
	 *                   != null) {
	 *  this.startBehavior(type, new ParameterValueList());
	 *                   }
	 *  }
	 *  }
	 *  else {
	 *  Debug.println("[startBehavior]
	 *                   Starting behavior for " + classifier.name + "...");
	 *  
	 *  boolean
	 *                   notYetStarted = true;
	 *  int i = 1;
	 *  while (notYetStarted &
	 *                   i <= this.classifierBehaviorExecutions.size()) {
	 *  notYetStarted =
	 *                   (this.classifierBehaviorExecutions.getValue(i-1).classifier !=
	 *                   classifier);
	 *  i = i + 1;
	 *  }
	 *  
	 *  if (notYetStarted)
	 *                   {
	 *  ClassifierBehaviorExecution newExecution = new
	 *                   ClassifierBehaviorExecution();
	 *  newExecution.objectActivation =
	 *                   this;
	 *  this.classifierBehaviorExecutions.addValue(newExecution);
	 *                   newExecution.execute(classifier, inputs);
	 *  }
	 *  }
	 *  
	 * <!-- end-model-doc -->
	 * @model classifierOrdered="false" inputsMany="true" inputsOrdered="false"
	 * @generated
	 */
	void startBehavior(fUML.Syntax.Classes.Kernel.Class classifier, EList<ParameterValue> inputs);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Stop this object activation by terminating all classifier behavior
	 *                   executions.
	 *  
	 *  ClassifierBehaviorExecutionList
	 *                   classifierBehaviorExecutions = this.classifierBehaviorExecutions;
	 *  for
	 *                   (int i = 0; i < classifierBehaviorExecutions.size(); i++) {
	 *                   ClassifierBehaviorExecution classifierBehaviorExecution =
	 *                   classifierBehaviorExecutions.getValue(i);
	 *                   classifierBehaviorExecution.terminate();
	 *  }
	 *  
	 *  
	 * <!-- end-model-doc -->
	 * @model
	 * @generated
	 */
	void stop();

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Register the given event accepter to wait for a dispatched signal
	 *                   event.
	 *  
	 *  Debug.println("[register] object = " +
	 *                   this.object);
	 *  Debug.println("[register] accepter = " +
	 *                   accepter);
	 *  
	 *                   this.waitingEventAccepters.addValue(accepter);
	 *  
	 * <!-- end-model-doc -->
	 * @model accepterRequired="true" accepterOrdered="false"
	 * @generated
	 */
	void register(EventAccepter accepter);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @model accepterRequired="true" accepterOrdered="false"
	 * @generated
	 */
	void unregister(EventAccepter accepter);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Add the given signal instance to the event pool and signal that a new
	 *                   signal instance has arrived.
	 *  
	 *                   this.eventPool.addValue((SignalInstance)(signalInstance.copy()));
	 *                   _send(new ArrivalSignal());
	 *  
	 *  
	 *  
	 * <!-- end-model-doc -->
	 * @model signalInstanceRequired="true" signalInstanceOrdered="false"
	 * @generated
	 */
	void send(SignalInstance signalInstance);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Get the next signal instance out of the event pool.
	 *  // If there is
	 *                   one or more waiting event accepters with triggers that match the signal instance,
	 *                   then dispatch it to exactly one of those waiting accepters.
	 *  
	 *  if
	 *                   (this.eventPool.size() > 0) {
	 *  SignalInstance signalInstance =
	 *                   this.getNextEvent();
	 *  
	 *  Debug.println("[dispatchNextEvent]
	 *                   signalInstance = " + signalInstance);
	 *  
	 *  intList
	 *                   matchingEventAccepterIndexes = new intList();
	 *  EventAccepterList
	 *                   waitingEventAccepters = this.waitingEventAccepters;
	 *  for (int i = 0; i
	 *                   < waitingEventAccepters.size(); i++) {
	 *  EventAccepter eventAccepter
	 *                   = waitingEventAccepters.getValue(i);
	 *  if
	 *                   (eventAccepter.match(signalInstance)) {
	 *                   matchingEventAccepterIndexes.addValue(i);
	 *  }
	 *  }
	 *  
	 *                   if (matchingEventAccepterIndexes.size() > 0) {
	 *  // *** Choose one
	 *                   matching event accepter non-deterministically. ***
	 *  int j =
	 *                   ((ChoiceStrategy)this.object.locus.factory.getStrategy("choice")).choose(matchingEventAccepterIndexes.size());
	 *                   EventAccepter selectedEventAccepter =
	 *                   this.waitingEventAccepters.getValue(matchingEventAccepterIndexes.getValue(j-1));
	 *                   this.waitingEventAccepters.removeValue(j-1);
	 *                   selectedEventAccepter.accept(signalInstance);
	 *  }
	 *  }
	 *                 
	 * <!-- end-model-doc -->
	 * @model
	 * @generated
	 */
	void dispatchNextEvent();

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @model kind="operation" required="true" ordered="false"
	 * @generated
	 */
	SignalInstance getNextEvent();

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @model
	 * @generated
	 */
	void _startObjectBehavior();

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @model signalRequired="true" signalOrdered="false"
	 * @generated
	 */
	void _send(Object signal);

} // ObjectActivation
